﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Prime31;

public class PlayerController : MonoBehaviour {
    public float gravity = -25f;
    public float runSpeed = 4f;
    public float DashSpeed = 8f;
    public float groundDamping = 20f; // how fast do we change direction? higher means faster
    public float inAirDamping = 5f;
    public float jumpHeight = 3f;
    public int JumpTime = 2;
    public bool CanControll;
    public int BeHitMask;
    public float HitValue=0;

    Animator MyAnimator;
    bool attack, walk, dash;
    bool jump;
    float Speed;
    int jumpTime;
    bool Attack
    {
        get
        {
            return attack;

        }

        set
        {
            attack = value;
            MyAnimator.SetBool("Attack", value);
        }
    }
    bool Walk
    {
        get
        {
            return walk;
        }

        set
        {
            walk = value;
            MyAnimator.SetBool("Walk", value);
        }
    }
    bool Jump
    {
        get
        {
            return jump;
        }

        set
        {
            jump = value;
            MyAnimator.SetBool("Jump", value);
        }
    }

    bool Dash
    {
        get
        {
            return dash;
        }

        set
        {
            dash = value;
            MyAnimator.SetBool("Dash", value);
            if (value) Speed = DashSpeed;
            else Speed = runSpeed;
        }
    }
    
    private float normalizedHorizontalSpeed = 0;

    private CharacterController2D _controller;
    public Vector3 _velocity;

    // Use this for initialization
    void Start () {
        MyAnimator = GetComponent<Animator>();
        _controller = GetComponent<CharacterController2D>();
        Speed = runSpeed;
        _controller.onControllerCollidedEvent += onControllerCollider;
        _controller.onTriggerEnterEvent += onTriggerEnterEvent;
        _controller.onTriggerExitEvent += onTriggerExitEvent;
    }
    #region Event Listeners

    void SetHitValue(float vlaue)
    {
        HitValue = vlaue;
    }

    void onControllerCollider(RaycastHit2D hit)
    {
        // bail out on plain old ground hits cause they arent very interesting
        if (hit.normal.y == 1f)
            return;

        // logs any collider hits if uncommented. it gets noisy so it is commented out for the demo
        //Debug.Log( "flags: " + _controller.collisionState + ", hit.normal: " + hit.normal );
    }


    void onTriggerEnterEvent(Collider2D col)
    {
        if (col.gameObject.layer == BeHitMask)
            MyAnimator.SetBool("OnHit", true);
        else
        {
            Vector3 v = col.gameObject.transform.localScale;
            v.x = Mathf.Abs(v.x);
            if (transform.localScale.x > 0f)
                v.x *= -1;
            col.gameObject.transform.localScale = v;
            col.gameObject.GetComponent<PlayerController>()._velocity.x += transform.localScale.x * HitValue;
            Debug.Log(HitValue);
        }
        //Debug.Log("onTriggerEnterEvent: " + col.gameObject.name+ col.gameObject.layer);
    }


    void onTriggerExitEvent(Collider2D col)
    {
        //Debug.Log("onTriggerExitEvent: " + col.gameObject.name);
    }

    #endregion

    // Update is called once per frame
    void Update()
    {
        bool MoveAble = MyAnimator.GetBool("CanMove");
        if (CanControll)
        {
            MyAnimator.SetBool("JumpAgain", false);
            if (_controller.isGrounded)
            {
                Jump = false;
                jumpTime = JumpTime;
            }
            else
            {
                Jump = true;
            }
            if (Input.GetKey(KeyCode.RightArrow) && MoveAble)
            {
                normalizedHorizontalSpeed = 1;
                if (transform.localScale.x < 0f)
                    transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);

                if (_controller.isGrounded)
                    Walk = true;
            }
            else if (Input.GetKey(KeyCode.LeftArrow) && MoveAble)
            {
                normalizedHorizontalSpeed = -1;
                if (transform.localScale.x > 0f)
                    transform.localScale = new Vector3(-transform.localScale.x, transform.localScale.y, transform.localScale.z);

                if (_controller.isGrounded)
                    Walk = true;
            }
            else
            {
                normalizedHorizontalSpeed = 0;

                if (_controller.isGrounded)
                    Walk = false;
            }
            if (Input.GetKeyDown(KeyCode.UpArrow) && MoveAble)
                if (_controller.isGrounded)
                {
                    _velocity.y = Mathf.Sqrt(2f * jumpHeight * -gravity);
                    Jump = true;
                }
                else if (jumpTime > 1)
                {
                    jumpTime--;
                    MyAnimator.SetBool("JumpAgain", true);
                    _velocity.y = Mathf.Sqrt(2f * jumpHeight * -gravity);
                    Jump = true;
                }
            if (Input.GetKey(KeyCode.A))
            {
                Dash = true;
            }
            else
            {
                Dash = false;
            }
            if (Input.GetKeyDown(KeyCode.Z))
            {
                Attack = true;
            }
        }
            // apply horizontal speed smoothing it. dont really do this with Lerp. Use SmoothDamp or something that provides more control
            var smoothedMovementFactor = _controller.isGrounded ? groundDamping : inAirDamping; // how fast do we change direction?
            _velocity.x = Mathf.Lerp(_velocity.x, normalizedHorizontalSpeed * Speed, Time.deltaTime * smoothedMovementFactor);

            // apply gravity before moving
            _velocity.y += gravity * Time.deltaTime;



            if (_velocity.y <= 0.1 && _controller.isGrounded && Input.GetKeyDown(KeyCode.DownArrow))
            {
                _velocity.y = -3f;
                _controller.ignoreOneWayPlatformsThisFrame = true;
            }
            _controller.move(_velocity * Time.deltaTime);

            // grab our current _velocity to use as a base for all calculations
            _velocity = _controller.velocity;


            /*
            if (Input.GetKeyDown(KeyCode.Z))
            {
                Attack = true;
            }
            else
            {
                Attack = false;
            }*/
        
    }


}
